<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\stat\daily;

use app\model\AccountApplyDetailModel;
use app\model\AccountApplyModel;
use app\model\AccountDailyStatModel;
use app\model\AccountPortModel;
use app\model\ClientAccountModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;

class AccountService extends DailyService implements DailyInterface
{
    /**
     * @var Model 媒体日流水模型
     */
    public Model $data;

    /**
     * @var Model 账户信息模型
     */
    public Model $account;

    /**
     * @var Model 汇总表模型
     */
    public Model $statData;

    /**
     * @var float 消耗
     */
    public float $cost;

    /**
     * @var float 现金消耗
     */
    public float $cashCost;

    /**
     * @var float 赠款消耗
     */
    public float $rewardCost;

    /**
     * @var float 余额
     */
    public float $balance;

    /**
     * 设置数据.
     */
    public function setData(Model $model): bool
    {
        $this->data = $model;
        return true;
    }

    /**
     * 过滤数据.
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function filter(): bool
    {
        $account = $this->getAccount($this->data->advertiser_id);
        if (! $account instanceof ClientAccountModel || ! $account->getKey()) {
            return $this->setError($this->data->advertiser_id . '账户数据不存在');
        }
        $this->account = $account;

        $cost = $this->getCost($this->data);
        $rewardCost = $this->getRewardCost($this->data);
        $cashCost = $this->getCashCost($this->data);
        $balance = $this->getBalance($this->data);
        if (! $cost && ! $rewardCost && ! $cashCost && ! $balance) {
            return $this->setError('空数据');
        }
        $this->cost = $cost;
        $this->cashCost = $cashCost;
        $this->rewardCost = $rewardCost;
        $this->balance = $balance;

        $statData = $this->getDailyModel($this->data->stat_date, $this->data->advertiser_id, $account->media_id);
        if (! $statData instanceof AccountDailyStatModel) {
            return $this->setError('汇总模型有误');
        }
        $this->statData = $statData;

        return true;
    }

    /**
     * 保存汇总数据.
     */
    public function saveStatData(): bool
    {
        $filterRes = $this->filter();
        if (! $filterRes) {
            return false;
        }
        $account = $this->account;
        $statData = $this->statData;
        $cost = $this->cost;
        $rewardCost = $this->rewardCost;
        $cashCost = $this->cashCost;
        $balance = $this->balance;
        $productId = $this->getProductId($this->data->advertiser_id);
        if (! $statData->getKey()) {
            $port = $this->getPort($this->data->advertiser_id);
            $data = [
                'advertiser_id' => $this->data->advertiser_id,
                'account_id' => $account->id,
                'client_id' => $account->client_id,
                'media_id' => $account->media_id,
                'product_id' => $productId,
                'port_id' => $port ? $port->port_id : 0,
                'account_type' => $account->account_type ? $account->account_type : 0,
                'stat_date' => $this->data->stat_date,
                'balance' => $balance,
                'cash_cost' => $cashCost,
                'cost' => $cost,
                'reward_cost' => $rewardCost,
                'staff_id' => $this->data->staff_id,
                'project_id' => $this->data->project_id,
            ];
            $statData->save($data);
        } else {
            if ($statData->cost != $cost || $statData->cash_cost != $cashCost || $statData->reward_cost != $rewardCost || $statData->balance != $balance) {
                $statData->cost = $cost;
                $statData->cash_cost = $cashCost;
                $statData->reward_cost = $rewardCost;
                $statData->balance = $balance;
                $statData->save();
            }
        }
        return true;
    }

    /**
     * 获取当前汇总表数据是否存在.
     * @param int $statDate 日期
     * @param ...$arg
     * @return AccountDailyStatModel|array|mixed|Model
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getDailyModel(int $statDate, ...$arg)
    {
        $where = [
            ['advertiser_id', '=', $arg[0]],
            ['stat_date', '=', $statDate],
        ];
        if (isset($arg[1])) {
            $where[] = ['media_id', '=', $arg[1]];
        }
        $res = AccountDailyStatModel::where($where)->find();
        return $res ?: new AccountDailyStatModel();
    }

    /**
     * 获取账户信息.
     * @param string $advertiserId 账户id
     * @return null|array|ClientAccountModel|mixed|Model|void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAccount(string $advertiserId = '')
    {
        return ClientAccountModel::where('advertiser_id', $advertiserId)->find();
    }

    /**
     * 获取端口信息.
     * @param string $advertiserId 账户id
     * @return null|AccountPortModel|array|mixed|Model|void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getPort(string $advertiserId = '')
    {
        return AccountPortModel::where('advertiser_id', $advertiserId)->find();
    }

    /**
     * 获取账户产品id.
     * @param string $advertiserId 账户id
     * @return int|mixed
     */
    public function getProductId(string $advertiserId = '')
    {
        $productId = 0;
        $applyId = AccountApplyDetailModel::where('advertiser_id', $advertiserId)->value('apply_id');
        if ($applyId) {
            $productId = AccountApplyModel::where('id', $applyId)->value('product_id');
        }
        return $productId;
    }

    /**
     * 归档.
     */
    public function archive(int $statDate)
    {
    }
}
